package com.geccocrawler.gecco.request;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.Map;

public abstract class AbstractHttpRequest implements HttpRequest, Comparable<HttpRequest>, Serializable {

    private static final long serialVersionUID = -7284636094595149962L;

    private String url;

    private String charset;

    private Map<String, String> parameters;

    private Map<String, String> cookies;

    private Map<String, String> headers;

    private long priority;

    public AbstractHttpRequest() {
        this.parameters = Maps.newHashMap();
        this.headers = Maps.newHashMap();
        this.cookies = Maps.newHashMap();
    }

    public AbstractHttpRequest(String url) {
        this();
        this.setUrl(url);
    }

    @Override
    public void clearHeader() {
        this.headers.clear();
    }

    @Override
    public void clearCookie() {
        this.cookies.clear();
    }

    @Override
    public void addCookie(String name, String value) {
        cookies.put(name, value);
    }

    @Override
    public String getCookie(String name) {
        return cookies.get(name);
    }

    @Override
    public void addParameter(String name, String value) {
        parameters.put(name, value);
    }

    @Override
    public void setParameters(Map<String, String> parameters) {
        this.parameters.putAll(parameters);
    }

    @Override
    public String getParameter(String name) {
        return parameters.get(name);
    }

    @Override
    public HttpRequest subRequest(String url) {
        try {
            //解决url的后缀问题
            url = url.trim().endsWith("/") ? url.trim().substring(0, url.length() - 1) : url.trim();
            HttpRequest request = (HttpRequest) clone();
            request.setUrl(url);
            request.refer(this.getUrl());
            return request;
        } catch (Exception ex) {
            ex.printStackTrace(System.out);
        }
        return null;
    }

    @Override
    public void addHeader(String name, String value) {
        headers.put(name, value);
    }

    @Override
    public String getUrl() {
        return url;
    }

    @Override
    public Map<String, String> getHeaders() {
        return headers;
    }

    @Override
    public void refer(String refer) {
        this.addHeader("Referer", refer);
    }

    @Override
    public Map<String, String> getParameters() {
        return parameters;
    }

    @Override
    public String getCharset() {
        return charset;
    }

    @Override
    public void setCharset(String charset) {
        this.charset = charset;
    }

    public void setCookies(Map<String, String> cookies) {
        this.cookies = cookies;
    }

    public void setHeaders(Map<String, String> headers) {
        this.headers = headers;
    }

    @Override
    public long getPriority() {
        return priority;
    }

    @Override
    public void setPriority(long prio) {
        this.priority = prio;
    }

    @Override
    public Map<String, String> getCookies() {
        return cookies;
    }

    @Override
    public void setUrl(String url) {
        this.url = StringUtils.substringBefore(url, "#");
    }

    /**
     * 数字小，优先级高
     */
    @Override
    public int compareTo(HttpRequest o) {
        return this.priority > o.getPriority() ? 1 : this.priority < o.getPriority() ? -1 : 0;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        //通过json的序列号和反序列化实现对象的深度clone
        return JSON.parseObject(JSON.toJSONString(this), this.getClass());
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((url == null) ? 0 : url.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        AbstractHttpRequest other = (AbstractHttpRequest) obj;
        String otherJson = JSON.toJSONString(other);
        String thisJson = JSON.toJSONString(this);
        return otherJson.equals(thisJson);
    }
}
